Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1815)

Unified Diff: mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc

Issue 258623005: First step at synchronizing client model changes with service. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6a63efa14f368558c73d056128a9d95279f89abe
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
@@ -0,0 +1,259 @@
+// Copyright 2014 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/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/public/cpp/bindings/allocation_scope.h"
+#include "mojo/public/interfaces/shell/shell.mojom.h"
+#include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
+
+namespace mojo {
+namespace services {
+namespace view_manager {
+
+class ViewManagerTransaction {
+ public:
+ virtual ~ViewManagerTransaction() {}
+
+ void Commit() {
+ DCHECK(!committed_);
+ DoCommit();
+ committed_ = true;
+ }
+
+ bool committed() const { return committed_; }
+ uint32_t change_id() const { return change_id_; }
+
+ // General callback to be used for commits to the service.
+ void OnActionCompleted(bool success) {
+ DCHECK(success);
+ DoActionCompleted(success);
+ synchronizer_->RemoveFromPendingQueue(this);
+ }
+
+ protected:
+ enum TransactionType {
+ // Node creation.
+ TYPE_CREATE_VIEW_TREE_NODE,
+ // Modifications to the hierarchy (addition of or removal of nodes from a
+ // parent.)
+ TYPE_HIERARCHY
+ };
+
+ ViewManagerTransaction(TransactionType transaction_type,
+ ViewManagerSynchronizer* synchronizer)
+ : transaction_type_(transaction_type),
+ change_id_(synchronizer->GetNextChangeId()),
+ committed_(false),
+ synchronizer_(synchronizer) {
+ }
+
+ // Overridden to perform transaction-specific commit actions.
+ virtual void DoCommit() = 0;
+
+ // Overridden to perform transaction-specific cleanup on commit ack from the
+ // service.
+ virtual void DoActionCompleted(bool success) = 0;
+
+ IViewManager* service() { return synchronizer_->service_.get(); }
+
+ uint32_t MakeTransportId(uint16_t id) {
+ return (synchronizer_->connection_id_ << 16) | id;
+ }
+
+ private:
+ const int transaction_type_;
sky 2014/04/29 04:14:06 int->TransactionType
+ const uint32_t change_id_;
+ bool committed_;
+ ViewManagerSynchronizer* synchronizer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
+};
+
+class CreateViewTreeNodeTransaction
+ : public ViewManagerTransaction {
+ public:
+ CreateViewTreeNodeTransaction(int node_id,
+ ViewManagerSynchronizer* synchronizer)
+ : ViewManagerTransaction(TYPE_CREATE_VIEW_TREE_NODE, synchronizer),
+ node_id_(node_id) {}
+ virtual ~CreateViewTreeNodeTransaction() {}
+
+ private:
+ // Overridden from ViewManagerTransaction:
+ virtual void DoCommit() OVERRIDE {
+ service()->CreateNode(
+ node_id_,
+ base::Bind(&ViewManagerTransaction::OnActionCompleted,
+ base::Unretained(this)));
+ }
+
+ void DoActionCompleted(bool success) {
+ // TODO(beng): Failure means we tried to create with an extant id for this
+ // connection. Figure out what to do.
+ }
+
+ const uint16_t node_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(CreateViewTreeNodeTransaction);
+};
+
+class HierarchyTransaction : public ViewManagerTransaction {
+ public:
+ enum HierarchyChangeType {
+ TYPE_ADD,
+ TYPE_REMOVE
+ };
+ HierarchyTransaction(HierarchyChangeType hierarchy_change_type,
+ int child_id,
sky 2014/04/29 04:14:06 uint16_t for child_id and parent_id, including mem
+ int parent_id,
+ ViewManagerSynchronizer* synchronizer)
+ : ViewManagerTransaction(TYPE_HIERARCHY, synchronizer),
+ hierarchy_change_type_(hierarchy_change_type),
+ child_id_(child_id),
+ parent_id_(parent_id) {}
+ virtual ~HierarchyTransaction() {}
+
+ private:
+ // Overridden from ViewManagerTransaction:
+ virtual void DoCommit() OVERRIDE {
+ switch (hierarchy_change_type_) {
+ case TYPE_ADD:
sky 2014/04/29 04:14:06 nit: spacing off, indent case statements 2 more.
+ service()->AddNode(MakeTransportId(parent_id_),
+ MakeTransportId(child_id_),
+ change_id(),
+ base::Bind(&ViewManagerTransaction::OnActionCompleted,
+ base::Unretained(this)));
+ break;
+ case TYPE_REMOVE:
+ service()->RemoveNodeFromParent(
+ MakeTransportId(child_id_),
+ change_id(),
+ base::Bind(&ViewManagerTransaction::OnActionCompleted,
+ base::Unretained(this)));
+ break;
+ }
+ }
+
+ void DoActionCompleted(bool success) {
+ // TODO(beng): Failure means either one of the nodes specified didn't exist,
+ // or we passed the same node id for both params. Roll back?
+ }
+
+ const HierarchyChangeType hierarchy_change_type_;
+ const int child_id_;
+ const int parent_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction);
+};
+
+ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
+ : view_manager_(view_manager),
+ connected_(false),
+ connection_id_(0),
+ next_id_(0),
+ next_change_id_(0) {
+ InterfacePipe<services::view_manager::IViewManager, AnyInterface>
+ view_manager_pipe;
+ AllocationScope scope;
+ ViewManagerPrivate(view_manager_).shell()->Connect(
+ "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass());
+ service_.reset(view_manager_pipe.handle_to_self.Pass(), this);
+}
+
+ViewManagerSynchronizer::~ViewManagerSynchronizer() {
+}
+
+int ViewManagerSynchronizer::CreateViewTreeNode() {
+ int id = next_id_++;
sky 2014/04/29 04:14:06 uint32_t
+ pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this));
+ ScheduleSync();
+ return id;
+}
+
+void ViewManagerSynchronizer::AddChild(int child_id, int parent_id) {
+ pending_transactions_.push_back(
+ new HierarchyTransaction(HierarchyTransaction::TYPE_ADD,
+ child_id,
+ parent_id,
+ this));
+ ScheduleSync();
+}
+
+void ViewManagerSynchronizer::RemoveChild(int child_id, int parent_id) {
+ pending_transactions_.push_back(
+ new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE,
+ child_id,
+ parent_id,
+ this));
+ ScheduleSync();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ViewManagerSynchronizer, IViewManagerClient implementation:
+
+void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) {
+ connected_ = true;
+ connection_id_ = connection_id;
+ ScheduleSync();
+}
+
+void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node,
+ uint32_t new_parent,
+ uint32_t old_parent,
+ int32_t change_id) {
+ if (change_id == 0) {
+ // TODO(beng): Apply changes from another client.
+ }
+}
+
+void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node,
+ uint32_t new_view_id,
+ uint32_t old_view_id,
+ int32_t change_id) {
+ // ..
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ViewManagerSynchronizer, private:
+
+void ViewManagerSynchronizer::ScheduleSync() {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&ViewManagerSynchronizer::DoSync, base::Unretained(this)));
+}
+
+void ViewManagerSynchronizer::DoSync() {
+ // The service connection may not be set up yet. OnConnectionEstablished()
+ // will schedule another sync when it is.
+ if (!connected_)
+ return;
+
+ Transactions::const_iterator it = pending_transactions_.begin();
+ for (; it != pending_transactions_.end(); ++it) {
+ if (!(*it)->committed())
+ (*it)->Commit();
+ }
+}
+
+int ViewManagerSynchronizer::GetNextChangeId() {
+ // TODO(beng): deal with change id collisions? Important in the "never ack'ed
+ // change" case mentioned in OnNodeHierarchyChanged().
+ // "0" is a special value passed to other connected clients, so we can't use
+ // it.
+ next_change_id_ = std::max(1u, ++next_change_id_);
+ return next_change_id_;
+}
+
+void ViewManagerSynchronizer::RemoveFromPendingQueue(
+ ViewManagerTransaction* transaction) {
+ DCHECK_EQ(transaction, pending_transactions_.front());
+ pending_transactions_.erase(pending_transactions_.begin());
+}
+
+} // namespace view_manager
+} // namespace services
+} // namespace mojo

Powered by Google App Engine
This is Rietveld 408576698