diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 00:44:48 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-13 00:44:48 +0000 |
commit | 85033389ec6567b21ecb5ee3fe1a4ab2492498be (patch) | |
tree | e91a0144c96102a6b660f6687019a971eec869a1 | |
parent | df69fbb9f8f136f961d59df99f717245ef98aa39 (diff) | |
download | chromium_src-85033389ec6567b21ecb5ee3fe1a4ab2492498be.zip chromium_src-85033389ec6567b21ecb5ee3fe1a4ab2492498be.tar.gz chromium_src-85033389ec6567b21ecb5ee3fe1a4ab2492498be.tar.bz2 |
Mojo: RemotePtr<S> + bindings changes for Peer attribute.
This adds an end-to-end test of the system w/ generated code as part of the CL. The generated code can be deleted once we have a GYP rule for generating code.
Review URL: https://codereview.chromium.org/66353002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234681 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 877 insertions, 30 deletions
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index f038fbc..44454c1 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -124,6 +124,10 @@ ], 'sources': [ 'public/tests/bindings_connector_unittest.cc', + 'public/tests/bindings_remote_ptr_unittest.cc', + 'public/tests/mojom/math_calculator.cc', + 'public/tests/mojom/math_calculator.h', + 'public/tests/mojom/math_calculator_internal.h', 'public/tests/system_core_unittest.cc', ], }, diff --git a/mojo/public/bindings/generators/cpp_templates/interface_declaration b/mojo/public/bindings/generators/cpp_templates/interface_declaration index aa6411f..3fa1b34 100644 --- a/mojo/public/bindings/generators/cpp_templates/interface_declaration +++ b/mojo/public/bindings/generators/cpp_templates/interface_declaration @@ -1,4 +1,11 @@ +class ${CLASS}Proxy; +class ${CLASS}Stub; +class $PEER; + class $CLASS { public: + typedef ${CLASS}Proxy _Proxy; + typedef ${CLASS}Stub _Stub; + typedef $PEER _Peer; $METHODS }; diff --git a/mojo/public/bindings/generators/cpp_templates/module.cc-template b/mojo/public/bindings/generators/cpp_templates/module.cc-template index 9c07187..2e0ee81 100644 --- a/mojo/public/bindings/generators/cpp_templates/module.cc-template +++ b/mojo/public/bindings/generators/cpp_templates/module.cc-template @@ -7,7 +7,7 @@ #include "mojo/public/bindings/lib/message_builder.h" #include "$INTERNAL_HEADER" -namespace sample { +namespace $NAMESPACE { namespace { #pragma pack(push, 1) @@ -26,7 +26,7 @@ $PARAM_DEFINITIONS $STRUCT_DEFINITIONS $INTERFACE_DEFINITIONS -} // namespace sample +} // namespace $NAMESPACE namespace mojo { namespace internal { diff --git a/mojo/public/bindings/generators/cpp_templates/params_serialization b/mojo/public/bindings/generators/cpp_templates/params_serialization index bc3a928..c3a57b5 100644 --- a/mojo/public/bindings/generators/cpp_templates/params_serialization +++ b/mojo/public/bindings/generators/cpp_templates/params_serialization @@ -1,5 +1,5 @@ template <> -class ObjectTraits<sample::Service_Frobinate_Params> { +class ObjectTraits<$CLASS> { public: static void EncodePointersAndHandles( $CLASS* $NAME, diff --git a/mojo/public/bindings/generators/cpp_templates/template_declaration b/mojo/public/bindings/generators/cpp_templates/template_declaration index f49c3ba..9b923e4 100644 --- a/mojo/public/bindings/generators/cpp_templates/template_declaration +++ b/mojo/public/bindings/generators/cpp_templates/template_declaration @@ -1,10 +1,10 @@ template <> -class ObjectTraits<sample::internal::$CLASS> { +class ObjectTraits<$NAMESPACE::internal::$CLASS> { public: static void EncodePointersAndHandles( - sample::internal::$CLASS* params, + $NAMESPACE::internal::$CLASS* params, std::vector<mojo::Handle>* handles); static bool DecodePointersAndHandles( - sample::internal::$CLASS* params, + $NAMESPACE::internal::$CLASS* params, const mojo::Message& message); }; diff --git a/mojo/public/bindings/generators/mojom.py b/mojo/public/bindings/generators/mojom.py index 4f789b7..1bda236 100644 --- a/mojo/public/bindings/generators/mojom.py +++ b/mojo/public/bindings/generators/mojom.py @@ -104,8 +104,9 @@ class Method(object): class Interface(object): - def __init__(self, name = None): + def __init__(self, name = None, peer = None): self.name = name + self.peer = peer self.methods = [] def AddMethod(self, name, ordinal = None): diff --git a/mojo/public/bindings/generators/mojom_cpp_generator.py b/mojo/public/bindings/generators/mojom_cpp_generator.py index e5c764e..f807f0f 100644 --- a/mojo/public/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/bindings/generators/mojom_cpp_generator.py @@ -311,7 +311,8 @@ class CPPGenerator(object): (method.name, ", ".join(params), method_postfix)) return template.substitute( CLASS=interface.name, - METHODS='.\n'.join(methods)) + PEER=interface.peer, + METHODS='\n'.join(methods)) def GetInterfaceClassDeclarations(self): template = self.GetTemplate("interface_declaration") diff --git a/mojo/public/bindings/generators/mojom_data.py b/mojo/public/bindings/generators/mojom_data.py index 3593511..d9b800a 100644 --- a/mojo/public/bindings/generators/mojom_data.py +++ b/mojo/public/bindings/generators/mojom_data.py @@ -127,12 +127,14 @@ def MethodFromData(kinds, data): def InterfaceToData(interface): return { istr(0, 'name'): interface.name, - istr(1, 'methods'): map(MethodToData, interface.methods) + istr(1, 'peer'): interface.peer, + istr(2, 'methods'): map(MethodToData, interface.methods) } def InterfaceFromData(kinds, data): interface = mojom.Interface() interface.name = data['name'] + interface.peer = data['peer'] interface.methods = map( lambda method: MethodFromData(kinds, method), data['methods']) return interface diff --git a/mojo/public/bindings/lib/remote_ptr.h b/mojo/public/bindings/lib/remote_ptr.h new file mode 100644 index 0000000..2905992 --- /dev/null +++ b/mojo/public/bindings/lib/remote_ptr.h @@ -0,0 +1,77 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_ +#define MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_ + +#include "mojo/public/bindings/lib/connector.h" + +namespace mojo { + +// A RemotePtr is a smart-pointer for managing the connection of a message pipe +// to an interface proxy. +// +// EXAMPLE +// +// On the client side of a service, RemotePtr might be used like so: +// +// class FooClientImpl : public FooClientStub { +// public: +// explicit FooClientImpl(mojo::Handle message_pipe) +// : foo_(message_pipe) { +// foo_.SetPeer(this); +// foo_.Ping(); +// } +// virtual void Pong() { +// ... +// } +// private: +// mojo::RemotePtr<Foo> foo_; +// }; +// +// On the implementation side of a service, RemotePtr might be used like so: +// +// class FooImpl : public FooStub { +// public: +// explicit FooImpl(mojo::Handle message_pipe) +// : client_(message_pipe) { +// client_.SetPeer(this); +// } +// virtual void Ping() { +// client_->Pong(); +// } +// private: +// mojo::RemotePtr<FooClient> client_; +// }; +// +template <typename S> +class RemotePtr { + public: + explicit RemotePtr(Handle message_pipe) + : connector_(message_pipe), + proxy_(&connector_) { + } + + S* get() { + return &proxy_; + } + + S* operator->() { + return get(); + } + + void SetPeer(typename S::_Peer::_Stub* peer) { + connector_.SetIncomingReceiver(peer); + } + + private: + Connector connector_; + typename S::_Proxy proxy_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(RemotePtr); +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_BINDINGS_LIB_REMOTE_PTR_H_ diff --git a/mojo/public/bindings/parser/mojo_translate.py b/mojo/public/bindings/parser/mojo_translate.py index 00b58a5..472e1ce 100755 --- a/mojo/public/bindings/parser/mojo_translate.py +++ b/mojo/public/bindings/parser/mojo_translate.py @@ -6,6 +6,7 @@ """Translate parse tree to Mojom IR""" +import os import sys @@ -36,6 +37,14 @@ def MapOrdinal(ordinal): return int(ordinal[1:]) # Strip leading '@' +def GetAttribute(attributes, name): + out = None + for attribute in attributes: + if attribute[0] == 'ATTRIBUTE' and attribute[1] == name: + out = attribute[2] + return out + + def MapFields(fields): out = [] for field in fields: @@ -74,16 +83,17 @@ class MojomBuilder(): def AddStruct(self, name, attributes, fields): struct = {} struct['name'] = name + # TODO(darin): Add support for |attributes| + #struct['attributes'] = MapAttributes(attributes) struct['fields'] = MapFields(fields) self.mojom['structs'].append(struct) - # TODO(darin): Add support for |attributes| def AddInterface(self, name, attributes, methods): interface = {} interface['name'] = name + interface['peer'] = GetAttribute(attributes, 'Peer') interface['methods'] = MapMethods(methods) self.mojom['interfaces'].append(interface) - # TODO(darin): Add support for |attributes| def AddModule(self, name, namespace, contents): self.mojom['name'] = name diff --git a/mojo/public/bindings/sample/generated/sample_service.cc b/mojo/public/bindings/sample/generated/sample_service.cc index 9209cb9..2befd7e 100644 --- a/mojo/public/bindings/sample/generated/sample_service.cc +++ b/mojo/public/bindings/sample/generated/sample_service.cc @@ -50,6 +50,35 @@ class Service_Frobinate_Params { }; MOJO_COMPILE_ASSERT(sizeof(Service_Frobinate_Params) == 24, bad_sizeof_Service_Frobinate_Params); + +const uint32_t kServiceClient_DidFrobinate_Name = 0; + +class ServiceClient_DidFrobinate_Params { + public: + static ServiceClient_DidFrobinate_Params* New(mojo::Buffer* buf) { + return new (buf->Allocate(sizeof(ServiceClient_DidFrobinate_Params))) + ServiceClient_DidFrobinate_Params(); + } + + void set_result(int32_t result) { result_ = result; } + + int32_t result() const { return result_; } + + private: + friend class mojo::internal::ObjectTraits<ServiceClient_DidFrobinate_Params>; + + ServiceClient_DidFrobinate_Params() { + _header_.num_bytes = sizeof(*this); + _header_.num_fields = 3; + } + + mojo::internal::StructHeader _header_; + int32_t result_; + uint8_t _pad0_[4]; +}; +MOJO_COMPILE_ASSERT(sizeof(ServiceClient_DidFrobinate_Params) == 16, + bad_sizeof_ServiceClient_DidFrobinate_Params); + #if defined(__clang__) #pragma clang diagnostic pop #endif @@ -134,6 +163,48 @@ bool ServiceStub::Accept(mojo::Message* message) { return true; } +ServiceClientProxy::ServiceClientProxy(mojo::MessageReceiver* receiver) + : receiver_(receiver) { +} + +void ServiceClientProxy::DidFrobinate(int32_t result) { + size_t payload_size = + mojo::internal::Align(sizeof(ServiceClient_DidFrobinate_Params)); + + + mojo::MessageBuilder builder(kServiceClient_DidFrobinate_Name, payload_size); + + ServiceClient_DidFrobinate_Params* params = + ServiceClient_DidFrobinate_Params::New(builder.buffer()); + + params->set_result(result); + + mojo::Message message; + mojo::internal::EncodePointersAndHandles(params, &message.handles); + + message.data = builder.Finish(); + + receiver_->Accept(&message); +} + + +bool ServiceClientStub::Accept(mojo::Message* message) { + switch (message->data->header.name) { + case kServiceClient_DidFrobinate_Name: { + ServiceClient_DidFrobinate_Params* params = + reinterpret_cast<ServiceClient_DidFrobinate_Params*>( + message->data->payload); + + if (!mojo::internal::DecodePointersAndHandles(params, *message)) + return false; + DidFrobinate(params->result()); + break; + } + + } + return true; +} + } // namespace sample namespace mojo { @@ -249,5 +320,20 @@ class ObjectTraits<sample::Service_Frobinate_Params> { } }; +template <> +class ObjectTraits<sample::ServiceClient_DidFrobinate_Params> { + public: + static void EncodePointersAndHandles( + sample::ServiceClient_DidFrobinate_Params* params, + std::vector<Handle>* handles) { + } + + static bool DecodePointersAndHandles( + sample::ServiceClient_DidFrobinate_Params* params, + const Message& message) { + return true; + } +}; + } // namespace internal } // namespace mojo diff --git a/mojo/public/bindings/sample/generated/sample_service.h b/mojo/public/bindings/sample/generated/sample_service.h index 9a77aa0..cb2e662 100644 --- a/mojo/public/bindings/sample/generated/sample_service.h +++ b/mojo/public/bindings/sample/generated/sample_service.h @@ -106,11 +106,32 @@ MOJO_COMPILE_ASSERT(sizeof(Foo) == 64, bad_sizeof_Foo); #pragma pack(pop) +class Service; +class ServiceProxy; +class ServiceStub; + +class ServiceClient; +class ServiceClientProxy; +class ServiceClientStub; + class Service { public: + typedef ServiceProxy _Proxy; + typedef ServiceStub _Stub; + typedef ServiceClient _Peer; + virtual void Frobinate(const Foo* foo, bool baz, mojo::Handle port) = 0; }; +class ServiceClient { + public: + typedef ServiceClientProxy _Proxy; + typedef ServiceClientStub _Stub; + typedef Service _Peer; + + virtual void DidFrobinate(int32_t result) = 0; +}; + class ServiceProxy : public Service { public: explicit ServiceProxy(mojo::MessageReceiver* receiver); @@ -122,11 +143,26 @@ class ServiceProxy : public Service { mojo::MessageReceiver* receiver_; }; +class ServiceClientProxy : public ServiceClient { + public: + explicit ServiceClientProxy(mojo::MessageReceiver* receiver); + + virtual void DidFrobinate(int32_t result) MOJO_OVERRIDE; + + private: + mojo::MessageReceiver* receiver_; +}; + class ServiceStub : public Service, public mojo::MessageReceiver { public: virtual bool Accept(mojo::Message* message) MOJO_OVERRIDE; }; +class ServiceClientStub : public ServiceClient, public mojo::MessageReceiver { + public: + virtual bool Accept(mojo::Message* message) MOJO_OVERRIDE; +}; + } // namespace sample #endif // MOJO_GENERATED_BINDINGS_SAMPLE_SERVICE_H_ diff --git a/mojo/public/bindings/sample/sample_service.idl b/mojo/public/bindings/sample/sample_service.idl index 3358a58..a1079a5 100644 --- a/mojo/public/bindings/sample/sample_service.idl +++ b/mojo/public/bindings/sample/sample_service.idl @@ -26,8 +26,14 @@ struct Foo { handle[] files @9; }; +[Peer=ServiceClient] interface Service { void Frobinate(Foo foo @0, bool baz @1, handle port @2) @0; }; +[Peer=Service] +interface ServiceClient { + void DidFrobinate(int32 result @0) @0; +}; + } diff --git a/mojo/public/bindings/sample/sample_service.mojom b/mojo/public/bindings/sample/sample_service.mojom index a2903f3..134739a 100644 --- a/mojo/public/bindings/sample/sample_service.mojom +++ b/mojo/public/bindings/sample/sample_service.mojom @@ -21,11 +21,21 @@ {'name': 'files', 'kind': 'a:h', 'ordinal': 9}]}], 'interfaces': [{ 'name': 'Service', + 'attributes': + {'Peer': 'ServiceClient'}, 'methods': [{ 'name': 'Frobinate', 'ordinal': 0, 'parameters': [ {'name': 'foo', 'kind': 'x:Foo', 'ordinal': 0}, {'name': 'baz', 'kind': 'b', 'ordinal': 1}, - {'name': 'port', 'kind': 'h', 'ordinal': 2}]}]}] + {'name': 'port', 'kind': 'h', 'ordinal': 2}]}]}, { + 'name': 'ServiceClient', + 'attributes': + {'Peer': 'Service'}, + 'methods': [{ + 'name': 'DidFrobinate', + 'ordinal': 0, + 'parameters': [ + {'name': 'result', 'kind': 'i32', 'ordinal': 0}]}]}] } diff --git a/mojo/public/tests/bindings_remote_ptr_unittest.cc b/mojo/public/tests/bindings_remote_ptr_unittest.cc new file mode 100644 index 0000000..ff0548e --- /dev/null +++ b/mojo/public/tests/bindings_remote_ptr_unittest.cc @@ -0,0 +1,117 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mojo/public/bindings/lib/remote_ptr.h" +#include "mojo/public/tests/mojom/math_calculator.h" +#include "mojo/public/tests/simple_bindings_support.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace mojo { +namespace test { + +class MathCalculatorImpl : public math::CalculatorStub { + public: + explicit MathCalculatorImpl(Handle pipe) + : ui_(pipe), + total_(0.0) { + ui_.SetPeer(this); + } + + virtual void Clear() MOJO_OVERRIDE { + ui_->Output(total_); + } + + virtual void Add(double value) MOJO_OVERRIDE { + total_ += value; + ui_->Output(total_); + } + + virtual void Multiply(double value) MOJO_OVERRIDE { + total_ *= value; + ui_->Output(total_); + } + + private: + RemotePtr<math::CalculatorUI> ui_; + double total_; +}; + +class MathCalculatorUIImpl : public math::CalculatorUIStub { + public: + explicit MathCalculatorUIImpl(Handle pipe) + : calculator_(pipe), + output_(0.0) { + calculator_.SetPeer(this); + } + + void Add(double value) { + calculator_->Add(value); + } + + void Subtract(double value) { + calculator_->Add(-value); + } + + void Multiply(double value) { + calculator_->Multiply(value); + } + + void Divide(double value) { + calculator_->Multiply(1.0 / value); + } + + double GetOutput() const { + return output_; + } + + private: + // math::CalculatorUI implementation: + virtual void Output(double value) MOJO_OVERRIDE { + output_ = value; + } + + RemotePtr<math::Calculator> calculator_; + double output_; +}; + +class BindingsRemotePtrTest : public testing::Test { + public: + BindingsRemotePtrTest() { + CreateMessagePipe(&pipe0_, &pipe1_); + } + + virtual ~BindingsRemotePtrTest() { + Close(pipe0_); + Close(pipe1_); + } + + void PumpMessages() { + bindings_support_.Process(); + } + + protected: + Handle pipe0_; + Handle pipe1_; + + private: + SimpleBindingsSupport bindings_support_; +}; + +TEST_F(BindingsRemotePtrTest, EndToEnd) { + // Suppose this is instantiated in a process that has pipe0_. + MathCalculatorImpl calculator(pipe0_); + + // Suppose this is instantiated in a process that has pipe1_. + MathCalculatorUIImpl calculator_ui(pipe1_); + + calculator_ui.Add(2.0); + calculator_ui.Multiply(5.0); + + PumpMessages(); + + EXPECT_EQ(10.0, calculator_ui.GetOutput()); +} + +} // namespace test +} // namespace mojo diff --git a/mojo/public/tests/math_calculator.mojom b/mojo/public/tests/math_calculator.mojom new file mode 100644 index 0000000..949a902 --- /dev/null +++ b/mojo/public/tests/math_calculator.mojom @@ -0,0 +1,19 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module math { + +[Peer=CalculatorUI] +interface Calculator { + void Clear() @0; + void Add(double value @0) @1; + void Multiply(double value @0) @2; +}; + +[Peer=Calculator] +interface CalculatorUI { + void Output(double value @0) @0; +}; + +} diff --git a/mojo/public/tests/mojom/DEPS b/mojo/public/tests/mojom/DEPS new file mode 100644 index 0000000..c2cf2d4 --- /dev/null +++ b/mojo/public/tests/mojom/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+.", +] diff --git a/mojo/public/tests/mojom/math_calculator.cc b/mojo/public/tests/mojom/math_calculator.cc new file mode 100644 index 0000000..c989b38 --- /dev/null +++ b/mojo/public/tests/mojom/math_calculator.cc @@ -0,0 +1,366 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "./math_calculator.h" + +#include "mojo/public/bindings/lib/message_builder.h" +#include "./math_calculator_internal.h" + +namespace math { +namespace { + +#pragma pack(push, 1) +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-private-field" +#endif +const uint32_t kCalculator_Clear_Name = 0; +class Calculator_Clear_Params { + public: + static Calculator_Clear_Params* New(mojo::Buffer* buf) { + return new (buf->Allocate(sizeof(Calculator_Clear_Params))) + Calculator_Clear_Params(); + } + + + + + + private: + friend class mojo::internal::ObjectTraits<Calculator_Clear_Params>; + + Calculator_Clear_Params() { + _header_.num_bytes = sizeof(*this); + _header_.num_fields = 3; + } + + mojo::internal::StructHeader _header_; + +}; +MOJO_COMPILE_ASSERT(sizeof(Calculator_Clear_Params) == 8, + bad_sizeof_Calculator_Clear_Params); + +const uint32_t kCalculator_Add_Name = 1; +class Calculator_Add_Params { + public: + static Calculator_Add_Params* New(mojo::Buffer* buf) { + return new (buf->Allocate(sizeof(Calculator_Add_Params))) + Calculator_Add_Params(); + } + + void set_value(double value) { value_ = value; } + + double value() const { return value_; } + + private: + friend class mojo::internal::ObjectTraits<Calculator_Add_Params>; + + Calculator_Add_Params() { + _header_.num_bytes = sizeof(*this); + _header_.num_fields = 3; + } + + mojo::internal::StructHeader _header_; + double value_; +}; +MOJO_COMPILE_ASSERT(sizeof(Calculator_Add_Params) == 16, + bad_sizeof_Calculator_Add_Params); + +const uint32_t kCalculator_Multiply_Name = 2; +class Calculator_Multiply_Params { + public: + static Calculator_Multiply_Params* New(mojo::Buffer* buf) { + return new (buf->Allocate(sizeof(Calculator_Multiply_Params))) + Calculator_Multiply_Params(); + } + + void set_value(double value) { value_ = value; } + + double value() const { return value_; } + + private: + friend class mojo::internal::ObjectTraits<Calculator_Multiply_Params>; + + Calculator_Multiply_Params() { + _header_.num_bytes = sizeof(*this); + _header_.num_fields = 3; + } + + mojo::internal::StructHeader _header_; + double value_; +}; +MOJO_COMPILE_ASSERT(sizeof(Calculator_Multiply_Params) == 16, + bad_sizeof_Calculator_Multiply_Params); + +const uint32_t kCalculatorUI_Output_Name = 0; +class CalculatorUI_Output_Params { + public: + static CalculatorUI_Output_Params* New(mojo::Buffer* buf) { + return new (buf->Allocate(sizeof(CalculatorUI_Output_Params))) + CalculatorUI_Output_Params(); + } + + void set_value(double value) { value_ = value; } + + double value() const { return value_; } + + private: + friend class mojo::internal::ObjectTraits<CalculatorUI_Output_Params>; + + CalculatorUI_Output_Params() { + _header_.num_bytes = sizeof(*this); + _header_.num_fields = 3; + } + + mojo::internal::StructHeader _header_; + double value_; +}; +MOJO_COMPILE_ASSERT(sizeof(CalculatorUI_Output_Params) == 16, + bad_sizeof_CalculatorUI_Output_Params); + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +#pragma pack(pop) + +} // namespace + + + +CalculatorProxy::CalculatorProxy(mojo::MessageReceiver* receiver) + : receiver_(receiver) { +} + +void CalculatorProxy::Clear() { + size_t payload_size = + mojo::internal::Align(sizeof(Calculator_Clear_Params)); + + + mojo::MessageBuilder builder(kCalculator_Clear_Name, payload_size); + + Calculator_Clear_Params* params = + Calculator_Clear_Params::New(builder.buffer()); + + + + mojo::Message message; + mojo::internal::EncodePointersAndHandles(params, &message.handles); + + message.data = builder.Finish(); + + receiver_->Accept(&message); +} + + +void CalculatorProxy::Add(double value) { + size_t payload_size = + mojo::internal::Align(sizeof(Calculator_Add_Params)); + + + mojo::MessageBuilder builder(kCalculator_Add_Name, payload_size); + + Calculator_Add_Params* params = + Calculator_Add_Params::New(builder.buffer()); + + params->set_value(value); + + mojo::Message message; + mojo::internal::EncodePointersAndHandles(params, &message.handles); + + message.data = builder.Finish(); + + receiver_->Accept(&message); +} + + +void CalculatorProxy::Multiply(double value) { + size_t payload_size = + mojo::internal::Align(sizeof(Calculator_Multiply_Params)); + + + mojo::MessageBuilder builder(kCalculator_Multiply_Name, payload_size); + + Calculator_Multiply_Params* params = + Calculator_Multiply_Params::New(builder.buffer()); + + params->set_value(value); + + mojo::Message message; + mojo::internal::EncodePointersAndHandles(params, &message.handles); + + message.data = builder.Finish(); + + receiver_->Accept(&message); +} + + +bool CalculatorStub::Accept(mojo::Message* message) { + switch (message->data->header.name) { + case kCalculator_Clear_Name: { + Calculator_Clear_Params* params = + reinterpret_cast<Calculator_Clear_Params*>( + message->data->payload); + + if (!mojo::internal::DecodePointersAndHandles(params, *message)) + return false; + Clear(); + break; + } + + case kCalculator_Add_Name: { + Calculator_Add_Params* params = + reinterpret_cast<Calculator_Add_Params*>( + message->data->payload); + + if (!mojo::internal::DecodePointersAndHandles(params, *message)) + return false; + Add(params->value()); + break; + } + + case kCalculator_Multiply_Name: { + Calculator_Multiply_Params* params = + reinterpret_cast<Calculator_Multiply_Params*>( + message->data->payload); + + if (!mojo::internal::DecodePointersAndHandles(params, *message)) + return false; + Multiply(params->value()); + break; + } + + } + return true; +} + + +CalculatorUIProxy::CalculatorUIProxy(mojo::MessageReceiver* receiver) + : receiver_(receiver) { +} + +void CalculatorUIProxy::Output(double value) { + size_t payload_size = + mojo::internal::Align(sizeof(CalculatorUI_Output_Params)); + + + mojo::MessageBuilder builder(kCalculatorUI_Output_Name, payload_size); + + CalculatorUI_Output_Params* params = + CalculatorUI_Output_Params::New(builder.buffer()); + + params->set_value(value); + + mojo::Message message; + mojo::internal::EncodePointersAndHandles(params, &message.handles); + + message.data = builder.Finish(); + + receiver_->Accept(&message); +} + + +bool CalculatorUIStub::Accept(mojo::Message* message) { + switch (message->data->header.name) { + case kCalculatorUI_Output_Name: { + CalculatorUI_Output_Params* params = + reinterpret_cast<CalculatorUI_Output_Params*>( + message->data->payload); + + if (!mojo::internal::DecodePointersAndHandles(params, *message)) + return false; + Output(params->value()); + break; + } + + } + return true; +} + + +} // namespace math + +namespace mojo { +namespace internal { + + + +template <> +class ObjectTraits<math::Calculator_Clear_Params> { + public: + static void EncodePointersAndHandles( + math::Calculator_Clear_Params* params, + std::vector<Handle>* handles) { + + + } + + static bool DecodePointersAndHandles( + math::Calculator_Clear_Params* params, + const Message& message) { + + + return true; + } +}; + +template <> +class ObjectTraits<math::Calculator_Add_Params> { + public: + static void EncodePointersAndHandles( + math::Calculator_Add_Params* params, + std::vector<Handle>* handles) { + + + } + + static bool DecodePointersAndHandles( + math::Calculator_Add_Params* params, + const Message& message) { + + + return true; + } +}; + +template <> +class ObjectTraits<math::Calculator_Multiply_Params> { + public: + static void EncodePointersAndHandles( + math::Calculator_Multiply_Params* params, + std::vector<Handle>* handles) { + + + } + + static bool DecodePointersAndHandles( + math::Calculator_Multiply_Params* params, + const Message& message) { + + + return true; + } +}; + +template <> +class ObjectTraits<math::CalculatorUI_Output_Params> { + public: + static void EncodePointersAndHandles( + math::CalculatorUI_Output_Params* params, + std::vector<Handle>* handles) { + + + } + + static bool DecodePointersAndHandles( + math::CalculatorUI_Output_Params* params, + const Message& message) { + + + return true; + } +}; + + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/tests/mojom/math_calculator.h b/mojo/public/tests/mojom/math_calculator.h new file mode 100644 index 0000000..3e2713d --- /dev/null +++ b/mojo/public/tests/mojom/math_calculator.h @@ -0,0 +1,79 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_GENERATED_BINDINGS_MATH_CALCULATOR_MATH_CALCULATOR_H_ +#define MOJO_GENERATED_BINDINGS_MATH_CALCULATOR_MATH_CALCULATOR_H_ + +#include "mojo/public/bindings/lib/bindings.h" +#include "mojo/public/bindings/lib/message.h" + +namespace math { + +#pragma pack(push, 1) + + +#pragma pack(pop) + +class CalculatorProxy; +class CalculatorStub; +class CalculatorUI; + +class Calculator { + public: + typedef CalculatorProxy _Proxy; + typedef CalculatorStub _Stub; + typedef CalculatorUI _Peer; + virtual void Clear() = 0; + virtual void Add(double value) = 0; + virtual void Multiply(double value) = 0; +}; + +class CalculatorUIProxy; +class CalculatorUIStub; +class Calculator; + +class CalculatorUI { + public: + typedef CalculatorUIProxy _Proxy; + typedef CalculatorUIStub _Stub; + typedef Calculator _Peer; + virtual void Output(double value) = 0; +}; + +class CalculatorProxy : public Calculator { + public: + explicit CalculatorProxy(mojo::MessageReceiver* receiver); + + virtual void Clear() MOJO_OVERRIDE; + virtual void Add(double value) MOJO_OVERRIDE; + virtual void Multiply(double value) MOJO_OVERRIDE; + + private: + mojo::MessageReceiver* receiver_; +}; + +class CalculatorUIProxy : public CalculatorUI { + public: + explicit CalculatorUIProxy(mojo::MessageReceiver* receiver); + + virtual void Output(double value) MOJO_OVERRIDE; + + private: + mojo::MessageReceiver* receiver_; +}; + +class CalculatorStub : public Calculator, public mojo::MessageReceiver { + public: + virtual bool Accept(mojo::Message* message) MOJO_OVERRIDE; +}; + +class CalculatorUIStub : public CalculatorUI, public mojo::MessageReceiver { + public: + virtual bool Accept(mojo::Message* message) MOJO_OVERRIDE; +}; + + +} // namespace math + +#endif // MOJO_GENERATED_BINDINGS_MATH_CALCULATOR_MATH_CALCULATOR_H_ diff --git a/mojo/public/tests/mojom/math_calculator_internal.h b/mojo/public/tests/mojom/math_calculator_internal.h new file mode 100644 index 0000000..3c56bd8 --- /dev/null +++ b/mojo/public/tests/mojom/math_calculator_internal.h @@ -0,0 +1,19 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_GENERATED_BINDINGS_MATH_CALCULATOR_MATH_CALCULATOR_INTERNAL_H_ +#define MOJO_GENERATED_BINDINGS_MATH_CALCULATOR_MATH_CALCULATOR_INTERNAL_H_ + +#include "mojo/public/bindings/lib/bindings_serialization.h" +#include "./math_calculator.h" + +namespace mojo { +namespace internal { + + + +} // namespace internal +} // namespace mojo + +#endif // MOJO_GENERATED_BINDINGS_MATH_CALCULATOR_MATH_CALCULATOR_INTERNAL_H_ diff --git a/mojo/public/tests/simple_bindings_support.cc b/mojo/public/tests/simple_bindings_support.cc index a59a66e..d8b079c 100644 --- a/mojo/public/tests/simple_bindings_support.cc +++ b/mojo/public/tests/simple_bindings_support.cc @@ -49,27 +49,31 @@ void SimpleBindingsSupport::CancelWait(AsyncWaitID async_wait_id) { } void SimpleBindingsSupport::Process() { - typedef std::pair<AsyncWaitCallback*, MojoResult> Result; - std::list<Result> results; + for (;;) { + typedef std::pair<AsyncWaitCallback*, MojoResult> Result; + std::list<Result> results; - WaiterList::iterator it = waiters_.begin(); - while (it != waiters_.end()) { - Waiter* waiter = *it; - MojoResult result; - if (IsReady(waiter->handle, waiter->flags, &result)) { - results.push_back(std::make_pair(waiter->callback, result)); - WaiterList::iterator doomed = it++; - waiters_.erase(doomed); - delete waiter; - } else { - ++it; + WaiterList::iterator it = waiters_.begin(); + while (it != waiters_.end()) { + Waiter* waiter = *it; + MojoResult result; + if (IsReady(waiter->handle, waiter->flags, &result)) { + results.push_back(std::make_pair(waiter->callback, result)); + WaiterList::iterator doomed = it++; + waiters_.erase(doomed); + delete waiter; + } else { + ++it; + } } - } - for (std::list<Result>::const_iterator it = results.begin(); - it != results.end(); - ++it) { - it->first->OnHandleReady(it->second); + for (std::list<Result>::const_iterator it = results.begin(); + it != results.end(); + ++it) { + it->first->OnHandleReady(it->second); + } + if (results.empty()) + break; } } |