| 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
|
| index 5fe22b4cb9583454cb77dc23e3863b2632c26fcf..609a90e2f9100d9d811f954e1f83cccbd4dffd30 100644
|
| --- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
|
| +++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
|
| @@ -8,12 +8,17 @@
|
| #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_observer.h"
|
| #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
|
| +#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
|
| +#include "mojo/services/public/cpp/view_manager/util.h"
|
|
|
| namespace mojo {
|
| namespace services {
|
| namespace view_manager {
|
|
|
| +const TransportNodeId kRootNodeId = 1;
|
| +
|
| class ViewManagerTransaction {
|
| public:
|
| virtual ~ViewManagerTransaction() {}
|
| @@ -21,6 +26,7 @@ class ViewManagerTransaction {
|
| void Commit() {
|
| DCHECK(!committed_);
|
| DoCommit();
|
| + synchronizer_->NotifyCommit();
|
| committed_ = true;
|
| }
|
|
|
| @@ -31,13 +37,15 @@ class ViewManagerTransaction {
|
| void OnActionCompleted(bool success) {
|
| DCHECK(success);
|
| DoActionCompleted(success);
|
| + synchronizer_->NotifyCommitResponse(success);
|
| synchronizer_->RemoveFromPendingQueue(this);
|
| }
|
|
|
| protected:
|
| enum TransactionType {
|
| - // Node creation.
|
| + // Node creation and destruction.
|
| TYPE_CREATE_VIEW_TREE_NODE,
|
| + TYPE_DESTROY_VIEW_TREE_NODE,
|
| // Modifications to the hierarchy (addition of or removal of nodes from a
|
| // parent.)
|
| TYPE_HIERARCHY
|
| @@ -60,8 +68,10 @@ class ViewManagerTransaction {
|
|
|
| IViewManager* service() { return synchronizer_->service_.get(); }
|
|
|
| - uint32_t MakeTransportId(uint16_t id) {
|
| - return (synchronizer_->connection_id_ << 16) | id;
|
| + TransportNodeId MakeTransportId(uint32_t id) {
|
| + if (id == kRootNodeId || HiWord(id) != 0)
|
| + return id;
|
| + return (synchronizer_->connection_id_ << 16) | LoWord(id);
|
| }
|
|
|
| private:
|
| @@ -73,8 +83,7 @@ class ViewManagerTransaction {
|
| DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
|
| };
|
|
|
| -class CreateViewTreeNodeTransaction
|
| - : public ViewManagerTransaction {
|
| +class CreateViewTreeNodeTransaction : public ViewManagerTransaction {
|
| public:
|
| CreateViewTreeNodeTransaction(uint16_t node_id,
|
| ViewManagerSynchronizer* synchronizer)
|
| @@ -90,7 +99,6 @@ class CreateViewTreeNodeTransaction
|
| base::Bind(&ViewManagerTransaction::OnActionCompleted,
|
| base::Unretained(this)));
|
| }
|
| -
|
| virtual void DoActionCompleted(bool success) OVERRIDE {
|
| // TODO(beng): Failure means we tried to create with an extant id for this
|
| // connection. Figure out what to do.
|
| @@ -101,6 +109,31 @@ class CreateViewTreeNodeTransaction
|
| DISALLOW_COPY_AND_ASSIGN(CreateViewTreeNodeTransaction);
|
| };
|
|
|
| +class DestroyViewTreeNodeTransaction : public ViewManagerTransaction {
|
| + public:
|
| + DestroyViewTreeNodeTransaction(TransportNodeId node_id,
|
| + ViewManagerSynchronizer* synchronizer)
|
| + : ViewManagerTransaction(TYPE_DESTROY_VIEW_TREE_NODE, synchronizer),
|
| + node_id_(node_id) {}
|
| + virtual ~DestroyViewTreeNodeTransaction() {}
|
| +
|
| + private:
|
| + // Overridden from ViewManagerTransaction:
|
| + virtual void DoCommit() OVERRIDE {
|
| + service()->DeleteNode(
|
| + node_id_,
|
| + change_id(),
|
| + base::Bind(&ViewManagerTransaction::OnActionCompleted,
|
| + base::Unretained(this)));
|
| + }
|
| + virtual void DoActionCompleted(bool success) OVERRIDE {
|
| + // TODO(beng): recovery?
|
| + }
|
| +
|
| + TransportNodeId node_id_;
|
| + DISALLOW_COPY_AND_ASSIGN(DestroyViewTreeNodeTransaction);
|
| +};
|
| +
|
| class HierarchyTransaction : public ViewManagerTransaction {
|
| public:
|
| enum HierarchyChangeType {
|
| @@ -108,8 +141,8 @@ class HierarchyTransaction : public ViewManagerTransaction {
|
| TYPE_REMOVE
|
| };
|
| HierarchyTransaction(HierarchyChangeType hierarchy_change_type,
|
| - uint16_t child_id,
|
| - uint16_t parent_id,
|
| + TransportNodeId child_id,
|
| + TransportNodeId parent_id,
|
| ViewManagerSynchronizer* synchronizer)
|
| : ViewManagerTransaction(TYPE_HIERARCHY, synchronizer),
|
| hierarchy_change_type_(hierarchy_change_type),
|
| @@ -145,8 +178,8 @@ class HierarchyTransaction : public ViewManagerTransaction {
|
| }
|
|
|
| const HierarchyChangeType hierarchy_change_type_;
|
| - const uint16_t child_id_;
|
| - const uint16_t parent_id_;
|
| + const TransportNodeId child_id_;
|
| + const TransportNodeId parent_id_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction);
|
| };
|
| @@ -155,7 +188,7 @@ ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
|
| : view_manager_(view_manager),
|
| connected_(false),
|
| connection_id_(0),
|
| - next_id_(0),
|
| + next_id_(1),
|
| next_change_id_(0) {
|
| InterfacePipe<services::view_manager::IViewManager, AnyInterface>
|
| view_manager_pipe;
|
| @@ -169,13 +202,20 @@ ViewManagerSynchronizer::~ViewManagerSynchronizer() {
|
| }
|
|
|
| uint16_t ViewManagerSynchronizer::CreateViewTreeNode() {
|
| - uint16_t id = next_id_++;
|
| + uint16_t id = ++next_id_;
|
| pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this));
|
| ScheduleSync();
|
| return id;
|
| }
|
|
|
| -void ViewManagerSynchronizer::AddChild(uint16_t child_id, uint16_t parent_id) {
|
| +void ViewManagerSynchronizer::DestroyViewTreeNode(TransportNodeId node_id) {
|
| + pending_transactions_.push_back(
|
| + new DestroyViewTreeNodeTransaction(node_id, this));
|
| + ScheduleSync();
|
| +}
|
| +
|
| +void ViewManagerSynchronizer::AddChild(TransportNodeId child_id,
|
| + TransportNodeId parent_id) {
|
| pending_transactions_.push_back(
|
| new HierarchyTransaction(HierarchyTransaction::TYPE_ADD,
|
| child_id,
|
| @@ -184,8 +224,8 @@ void ViewManagerSynchronizer::AddChild(uint16_t child_id, uint16_t parent_id) {
|
| ScheduleSync();
|
| }
|
|
|
| -void ViewManagerSynchronizer::RemoveChild(uint16_t child_id,
|
| - uint16_t parent_id) {
|
| +void ViewManagerSynchronizer::RemoveChild(TransportNodeId child_id,
|
| + TransportNodeId parent_id) {
|
| pending_transactions_.push_back(
|
| new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE,
|
| child_id,
|
| @@ -194,6 +234,15 @@ void ViewManagerSynchronizer::RemoveChild(uint16_t child_id,
|
| ScheduleSync();
|
| }
|
|
|
| +void ViewManagerSynchronizer::BuildNodeTree(
|
| + const Callback<void()>& callback) {
|
| + service_->GetNodeTree(
|
| + 1,
|
| + base::Bind(&ViewManagerSynchronizer::OnTreeReceived,
|
| + base::Unretained(this),
|
| + callback));
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // ViewManagerSynchronizer, IViewManagerClient implementation:
|
|
|
| @@ -201,6 +250,9 @@ void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) {
|
| connected_ = true;
|
| connection_id_ = connection_id;
|
| ScheduleSync();
|
| + FOR_EACH_OBSERVER(ViewManagerObserver,
|
| + *ViewManagerPrivate(view_manager_).observers(),
|
| + OnViewManagerConnected(view_manager_));
|
| }
|
|
|
| void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node,
|
| @@ -250,12 +302,53 @@ uint32_t ViewManagerSynchronizer::GetNextChangeId() {
|
| return next_change_id_;
|
| }
|
|
|
| +void ViewManagerSynchronizer::NotifyCommit() {
|
| + FOR_EACH_OBSERVER(ViewManagerObserver,
|
| + *ViewManagerPrivate(view_manager_).observers(),
|
| + OnCommit(view_manager_));
|
| +}
|
| +
|
| +void ViewManagerSynchronizer::NotifyCommitResponse(bool success) {
|
| + FOR_EACH_OBSERVER(ViewManagerObserver,
|
| + *ViewManagerPrivate(view_manager_).observers(),
|
| + OnCommitResponse(view_manager_, success));
|
| +}
|
| +
|
| void ViewManagerSynchronizer::RemoveFromPendingQueue(
|
| ViewManagerTransaction* transaction) {
|
| DCHECK_EQ(transaction, pending_transactions_.front());
|
| pending_transactions_.erase(pending_transactions_.begin());
|
| }
|
|
|
| +void ViewManagerSynchronizer::OnTreeReceived(
|
| + const Callback<void()>& callback,
|
| + const Array<INode>& nodes) {
|
| + std::vector<ViewTreeNode*> parents;
|
| + ViewTreeNode* root = NULL;
|
| + ViewTreeNode* last_node = NULL;
|
| + for (size_t i = 0; i < nodes.size(); ++i) {
|
| + if (last_node && nodes[i].parent_id() == last_node->id()) {
|
| + parents.push_back(last_node);
|
| + } else if (!parents.empty()) {
|
| + while (parents.back()->id() != nodes[i].parent_id())
|
| + parents.pop_back();
|
| + }
|
| + // We don't use the ctor that takes a ViewManager here, since it will call
|
| + // back to the service and attempt to create a new node.
|
| + ViewTreeNode* node = new ViewTreeNode;
|
| + ViewTreeNodePrivate private_node(node);
|
| + private_node.set_view_manager(view_manager_);
|
| + private_node.set_id(nodes[i].node_id());
|
| + if (!parents.empty())
|
| + ViewTreeNodePrivate(parents.back()).LocalAddChild(node);
|
| + if (!last_node)
|
| + root = node;
|
| + last_node = node;
|
| + }
|
| + ViewManagerPrivate(view_manager_).set_tree(root);
|
| + callback.Run();
|
| +}
|
| +
|
| } // namespace view_manager
|
| } // namespace services
|
| } // namespace mojo
|
|
|