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 886b5fdad1785584071144a258c61055eff91a74..e04b73ff3d99bb944694b6ed27f271e2efd03c24 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 |
@@ -10,6 +10,7 @@ |
#include "mojo/public/cpp/shell/service.h" |
#include "mojo/public/interfaces/shell/shell.mojom.h" |
#include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h" |
+#include "mojo/services/public/cpp/view_manager/lib/view_private.h" |
#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h" |
#include "mojo/services/public/cpp/view_manager/util.h" |
@@ -17,9 +18,39 @@ namespace mojo { |
namespace services { |
namespace view_manager { |
-TransportNodeId MakeTransportNodeId(uint16_t connection_id, |
- uint16_t local_node_id) { |
- return (connection_id << 16) | local_node_id; |
+uint32_t MakeTransportId(uint16_t connection_id, uint16_t local_id) { |
+ return (connection_id << 16) | local_id; |
+} |
+ |
+// Helper called to construct a local node/view object from transport data. |
+ViewTreeNode* AddNodeToViewManager(ViewManager* manager, |
+ ViewTreeNode* parent, |
+ TransportNodeId node_id, |
+ TransportViewId view_id) { |
+ // 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 = ViewTreeNodePrivate::LocalCreate(); |
+ ViewTreeNodePrivate private_node(node); |
+ private_node.set_view_manager(manager); |
+ private_node.set_id(node_id); |
+ if (parent) |
+ ViewTreeNodePrivate(parent).LocalAddChild(node); |
+ ViewManagerPrivate private_manager(manager); |
+ private_manager.AddNode(node->id(), node); |
+ |
+ // View. |
+ if (view_id != 0) { |
+ View* view = ViewPrivate::LocalCreate(); |
+ ViewPrivate private_view(view); |
+ private_view.set_view_manager(manager); |
+ private_view.set_id(view_id); |
+ private_view.set_node(node); |
+ // TODO(beng): this broadcasts notifications locally... do we want this? I |
+ // don't think so. same story for LocalAddChild above! |
+ private_node.LocalSetActiveView(view); |
+ private_manager.AddView(view->id(), view); |
+ } |
+ return node; |
} |
class ViewManagerTransaction { |
@@ -44,12 +75,17 @@ class ViewManagerTransaction { |
protected: |
enum TransactionType { |
+ // View creation and destruction. |
+ TYPE_CREATE_VIEW, |
+ TYPE_DESTROY_VIEW, |
// 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 |
+ TYPE_HIERARCHY, |
+ // View replacement. |
+ TYPE_SET_ACTIVE_VIEW |
}; |
ViewManagerTransaction(TransactionType transaction_type, |
@@ -78,6 +114,57 @@ class ViewManagerTransaction { |
DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction); |
}; |
+class CreateViewTransaction : public ViewManagerTransaction { |
+ public: |
+ CreateViewTransaction(uint16_t view_id, |
+ ViewManagerSynchronizer* synchronizer) |
+ : ViewManagerTransaction(TYPE_CREATE_VIEW, synchronizer), |
+ view_id_(view_id) {} |
+ virtual ~CreateViewTransaction() {} |
+ |
+ private: |
+ // Overridden from ViewManagerTransaction: |
+ virtual void DoCommit() OVERRIDE { |
+ service()->CreateView( |
+ view_id_, |
+ base::Bind(&ViewManagerTransaction::OnActionCompleted, |
+ base::Unretained(this))); |
+ } |
+ virtual void DoActionCompleted(bool success) OVERRIDE { |
+ // TODO(beng): failure. |
+ } |
+ |
+ const uint16_t view_id_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CreateViewTransaction); |
+}; |
+ |
+class DestroyViewTransaction : public ViewManagerTransaction { |
+ public: |
+ DestroyViewTransaction(TransportViewId view_id, |
+ ViewManagerSynchronizer* synchronizer) |
+ : ViewManagerTransaction(TYPE_DESTROY_VIEW, synchronizer), |
+ view_id_(view_id) {} |
+ virtual ~DestroyViewTransaction() {} |
+ |
+ private: |
+ // Overridden from ViewManagerTransaction: |
+ virtual void DoCommit() OVERRIDE { |
+ service()->DeleteView( |
+ view_id_, |
+ change_id(), |
+ base::Bind(&ViewManagerTransaction::OnActionCompleted, |
+ base::Unretained(this))); |
+ } |
+ virtual void DoActionCompleted(bool success) OVERRIDE { |
+ // TODO(beng): recovery? |
+ } |
+ |
+ const TransportViewId view_id_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DestroyViewTransaction); |
+}; |
+ |
class CreateViewTreeNodeTransaction : public ViewManagerTransaction { |
public: |
CreateViewTreeNodeTransaction(uint16_t node_id, |
@@ -125,7 +212,7 @@ class DestroyViewTreeNodeTransaction : public ViewManagerTransaction { |
// TODO(beng): recovery? |
} |
- TransportNodeId node_id_; |
+ const TransportNodeId node_id_; |
DISALLOW_COPY_AND_ASSIGN(DestroyViewTreeNodeTransaction); |
}; |
@@ -179,6 +266,36 @@ class HierarchyTransaction : public ViewManagerTransaction { |
DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction); |
}; |
+class SetActiveViewTransaction : public ViewManagerTransaction { |
+ public: |
+ SetActiveViewTransaction(TransportNodeId node_id, |
+ TransportViewId view_id, |
+ ViewManagerSynchronizer* synchronizer) |
+ : ViewManagerTransaction(TYPE_SET_ACTIVE_VIEW, synchronizer), |
+ node_id_(node_id), |
+ view_id_(view_id) {} |
+ virtual ~SetActiveViewTransaction() {} |
+ |
+ private: |
+ // Overridden from ViewManagerTransaction: |
+ virtual void DoCommit() OVERRIDE { |
+ service()->SetView( |
+ node_id_, |
+ view_id_, |
+ change_id(), |
+ base::Bind(&ViewManagerTransaction::OnActionCompleted, |
+ base::Unretained(this))); |
+ } |
+ virtual void DoActionCompleted(bool success) OVERRIDE { |
+ // TODO(beng): recovery? |
+ } |
+ |
+ const TransportNodeId node_id_; |
+ const TransportViewId view_id_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SetActiveViewTransaction); |
+}; |
+ |
ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager) |
: view_manager_(view_manager), |
connected_(false), |
@@ -212,7 +329,7 @@ TransportNodeId ViewManagerSynchronizer::CreateViewTreeNode() { |
uint16_t id = ++next_id_; |
pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this)); |
ScheduleSync(); |
- return MakeTransportNodeId(connection_id_, id); |
+ return MakeTransportId(connection_id_, id); |
} |
void ViewManagerSynchronizer::DestroyViewTreeNode(TransportNodeId node_id) { |
@@ -222,6 +339,20 @@ void ViewManagerSynchronizer::DestroyViewTreeNode(TransportNodeId node_id) { |
ScheduleSync(); |
} |
+TransportViewId ViewManagerSynchronizer::CreateView() { |
+ DCHECK(connected_); |
+ uint16_t id = ++next_id_; |
+ pending_transactions_.push_back(new CreateViewTransaction(id, this)); |
+ ScheduleSync(); |
+ return MakeTransportId(connection_id_, id); |
+} |
+ |
+void ViewManagerSynchronizer::DestroyView(TransportViewId view_id) { |
+ DCHECK(connected_); |
+ pending_transactions_.push_back(new DestroyViewTransaction(view_id, this)); |
+ ScheduleSync(); |
+} |
+ |
void ViewManagerSynchronizer::AddChild(TransportNodeId child_id, |
TransportNodeId parent_id) { |
DCHECK(connected_); |
@@ -248,6 +379,18 @@ bool ViewManagerSynchronizer::OwnsNode(TransportNodeId id) const { |
return HiWord(id) == connection_id_; |
} |
+bool ViewManagerSynchronizer::OwnsView(TransportViewId id) const { |
+ return HiWord(id) == connection_id_; |
+} |
+ |
+void ViewManagerSynchronizer::SetActiveView(TransportNodeId node_id, |
+ TransportViewId view_id) { |
+ DCHECK(connected_); |
+ pending_transactions_.push_back( |
+ new SetActiveViewTransaction(node_id, view_id, this)); |
+ ScheduleSync(); |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// ViewManagerSynchronizer, IViewManagerClient implementation: |
@@ -277,6 +420,8 @@ void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node_id, |
private_node.set_view_manager(view_manager_); |
private_node.set_id(node_id); |
ViewManagerPrivate(view_manager_).AddNode(node->id(), node); |
+ |
+ // TODO(beng): view changes. |
} |
if (new_parent) |
ViewTreeNodePrivate(new_parent).LocalAddChild(node); |
@@ -285,11 +430,26 @@ void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node_id, |
} |
} |
-void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node, |
+void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node_id, |
uint32_t new_view_id, |
uint32_t old_view_id, |
uint32_t change_id) { |
- // .. |
+ if (change_id == 0) { |
+ ViewTreeNode* node = view_manager_->GetNodeById(node_id); |
+ View* new_view = view_manager_->GetViewById(new_view_id); |
+ if (!new_view && new_view_id != 0) { |
+ // This client wasn't aware of this View until now. |
+ new_view = ViewPrivate::LocalCreate(); |
+ ViewPrivate private_view(new_view); |
+ private_view.set_view_manager(view_manager_); |
+ private_view.set_id(new_view_id); |
+ private_view.set_node(node); |
+ ViewManagerPrivate(view_manager_).AddView(new_view->id(), new_view); |
+ } |
+ View* old_view = view_manager_->GetViewById(old_view_id); |
+ DCHECK_EQ(old_view, node->active_view()); |
+ ViewTreeNodePrivate(node).LocalSetActiveView(new_view); |
+ } |
} |
void ViewManagerSynchronizer::OnNodeDeleted(uint32_t node_id, |
@@ -301,6 +461,15 @@ void ViewManagerSynchronizer::OnNodeDeleted(uint32_t node_id, |
} |
} |
+void ViewManagerSynchronizer::OnViewDeleted(uint32_t view_id, |
+ uint32_t change_id) { |
+ if (change_id == 0) { |
+ View* view = view_manager_->GetViewById(view_id); |
+ if (view) |
+ ViewPrivate(view).LocalDestroy(); |
+ } |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// ViewManagerSynchronizer, private: |
@@ -342,6 +511,7 @@ void ViewManagerSynchronizer::RemoveFromPendingQueue( |
void ViewManagerSynchronizer::OnRootTreeReceived( |
const Array<INode>& nodes) { |
+ ViewManagerPrivate private_manager(view_manager_); |
std::vector<ViewTreeNode*> parents; |
ViewTreeNode* root = NULL; |
ViewTreeNode* last_node = NULL; |
@@ -352,20 +522,16 @@ void ViewManagerSynchronizer::OnRootTreeReceived( |
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 = ViewTreeNodePrivate::LocalCreate(); |
- 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); |
+ ViewTreeNode* node = |
+ AddNodeToViewManager(view_manager_, |
+ !parents.empty() ? parents.back() : NULL, |
+ nodes[i].node_id(), |
+ nodes[i].view_id()); |
if (!last_node) |
root = node; |
last_node = node; |
- ViewManagerPrivate(view_manager_).AddNode(node->id(), node); |
} |
- ViewManagerPrivate(view_manager_).set_root(root); |
+ private_manager.set_root(root); |
if (init_loop_) |
init_loop_->Quit(); |
} |