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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "mojo/public/cpp/bindings/allocation_scope.h"
10 #include "mojo/public/interfaces/shell/shell.mojom.h"
11 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
12
13 namespace mojo {
14 namespace services {
15 namespace view_manager {
16
17 class ViewManagerTransaction {
18 public:
19 virtual ~ViewManagerTransaction() {}
20
21 void Commit() {
22 DCHECK(!committed_);
23 DoCommit();
24 committed_ = true;
25 }
26
27 bool committed() const { return committed_; }
28 uint32_t change_id() const { return change_id_; }
29
30 // General callback to be used for commits to the service.
31 void OnActionCompleted(bool success) {
32 DCHECK(success);
33 DoActionCompleted(success);
34 synchronizer_->RemoveFromPendingQueue(this);
35 }
36
37 protected:
38 enum TransactionType {
39 // Node creation.
40 TYPE_CREATE_VIEW_TREE_NODE,
41 // Modifications to the hierarchy (addition of or removal of nodes from a
42 // parent.)
43 TYPE_HIERARCHY
44 };
45
46 ViewManagerTransaction(TransactionType transaction_type,
47 ViewManagerSynchronizer* synchronizer)
48 : transaction_type_(transaction_type),
49 change_id_(synchronizer->GetNextChangeId()),
50 committed_(false),
51 synchronizer_(synchronizer) {
52 }
53
54 // Overridden to perform transaction-specific commit actions.
55 virtual void DoCommit() = 0;
56
57 // Overridden to perform transaction-specific cleanup on commit ack from the
58 // service.
59 virtual void DoActionCompleted(bool success) = 0;
60
61 IViewManager* service() { return synchronizer_->service_.get(); }
62
63 uint32_t MakeTransportId(uint16_t id) {
64 return (synchronizer_->connection_id_ << 16) | id;
65 }
66
67 private:
68 const TransactionType transaction_type_;
69 const uint32_t change_id_;
70 bool committed_;
71 ViewManagerSynchronizer* synchronizer_;
72
73 DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
74 };
75
76 class CreateViewTreeNodeTransaction
77 : public ViewManagerTransaction {
78 public:
79 CreateViewTreeNodeTransaction(uint16_t node_id,
80 ViewManagerSynchronizer* synchronizer)
81 : ViewManagerTransaction(TYPE_CREATE_VIEW_TREE_NODE, synchronizer),
82 node_id_(node_id) {}
83 virtual ~CreateViewTreeNodeTransaction() {}
84
85 private:
86 // Overridden from ViewManagerTransaction:
87 virtual void DoCommit() OVERRIDE {
88 service()->CreateNode(
89 node_id_,
90 base::Bind(&ViewManagerTransaction::OnActionCompleted,
91 base::Unretained(this)));
92 }
93
94 virtual void DoActionCompleted(bool success) OVERRIDE {
95 // TODO(beng): Failure means we tried to create with an extant id for this
96 // connection. Figure out what to do.
97 }
98
99 const uint16_t node_id_;
100
101 DISALLOW_COPY_AND_ASSIGN(CreateViewTreeNodeTransaction);
102 };
103
104 class HierarchyTransaction : public ViewManagerTransaction {
105 public:
106 enum HierarchyChangeType {
107 TYPE_ADD,
108 TYPE_REMOVE
109 };
110 HierarchyTransaction(HierarchyChangeType hierarchy_change_type,
111 uint16_t child_id,
112 uint16_t parent_id,
113 ViewManagerSynchronizer* synchronizer)
114 : ViewManagerTransaction(TYPE_HIERARCHY, synchronizer),
115 hierarchy_change_type_(hierarchy_change_type),
116 child_id_(child_id),
117 parent_id_(parent_id) {}
118 virtual ~HierarchyTransaction() {}
119
120 private:
121 // Overridden from ViewManagerTransaction:
122 virtual void DoCommit() OVERRIDE {
123 switch (hierarchy_change_type_) {
124 case TYPE_ADD:
125 service()->AddNode(
126 MakeTransportId(parent_id_),
127 MakeTransportId(child_id_),
128 change_id(),
129 base::Bind(&ViewManagerTransaction::OnActionCompleted,
130 base::Unretained(this)));
131 break;
132 case TYPE_REMOVE:
133 service()->RemoveNodeFromParent(
134 MakeTransportId(child_id_),
135 change_id(),
136 base::Bind(&ViewManagerTransaction::OnActionCompleted,
137 base::Unretained(this)));
138 break;
139 }
140 }
141
142 virtual void DoActionCompleted(bool success) OVERRIDE {
143 // TODO(beng): Failure means either one of the nodes specified didn't exist,
144 // or we passed the same node id for both params. Roll back?
145 }
146
147 const HierarchyChangeType hierarchy_change_type_;
148 const uint16_t child_id_;
149 const uint16_t parent_id_;
150
151 DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction);
152 };
153
154 ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
155 : view_manager_(view_manager),
156 connected_(false),
157 connection_id_(0),
158 next_id_(0),
159 next_change_id_(0) {
160 InterfacePipe<services::view_manager::IViewManager, AnyInterface>
161 view_manager_pipe;
162 AllocationScope scope;
163 ViewManagerPrivate(view_manager_).shell()->Connect(
164 "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass());
165 service_.reset(view_manager_pipe.handle_to_self.Pass(), this);
166 }
167
168 ViewManagerSynchronizer::~ViewManagerSynchronizer() {
169 }
170
171 uint16_t ViewManagerSynchronizer::CreateViewTreeNode() {
172 uint16_t id = next_id_++;
173 pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this));
174 ScheduleSync();
175 return id;
176 }
177
178 void ViewManagerSynchronizer::AddChild(uint16_t child_id, uint16_t parent_id) {
179 pending_transactions_.push_back(
180 new HierarchyTransaction(HierarchyTransaction::TYPE_ADD,
181 child_id,
182 parent_id,
183 this));
184 ScheduleSync();
185 }
186
187 void ViewManagerSynchronizer::RemoveChild(uint16_t child_id,
188 uint16_t parent_id) {
189 pending_transactions_.push_back(
190 new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE,
191 child_id,
192 parent_id,
193 this));
194 ScheduleSync();
195 }
196
197 ////////////////////////////////////////////////////////////////////////////////
198 // ViewManagerSynchronizer, IViewManagerClient implementation:
199
200 void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) {
201 connected_ = true;
202 connection_id_ = connection_id;
203 ScheduleSync();
204 }
205
206 void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node,
207 uint32_t new_parent,
208 uint32_t old_parent,
209 uint32_t change_id) {
210 if (change_id == 0) {
211 // TODO(beng): Apply changes from another client.
212 }
213 }
214
215 void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node,
216 uint32_t new_view_id,
217 uint32_t old_view_id,
218 uint32_t change_id) {
219 // ..
220 }
221
222 ////////////////////////////////////////////////////////////////////////////////
223 // ViewManagerSynchronizer, private:
224
225 void ViewManagerSynchronizer::ScheduleSync() {
226 base::MessageLoop::current()->PostTask(
227 FROM_HERE,
228 base::Bind(&ViewManagerSynchronizer::DoSync, base::Unretained(this)));
229 }
230
231 void ViewManagerSynchronizer::DoSync() {
232 // The service connection may not be set up yet. OnConnectionEstablished()
233 // will schedule another sync when it is.
234 if (!connected_)
235 return;
236
237 Transactions::const_iterator it = pending_transactions_.begin();
238 for (; it != pending_transactions_.end(); ++it) {
239 if (!(*it)->committed())
240 (*it)->Commit();
241 }
242 }
243
244 uint32_t ViewManagerSynchronizer::GetNextChangeId() {
245 // TODO(beng): deal with change id collisions? Important in the "never ack'ed
246 // change" case mentioned in OnNodeHierarchyChanged().
247 // "0" is a special value passed to other connected clients, so we can't use
248 // it.
249 next_change_id_ = std::max(1u, next_change_id_ + 1);
250 return next_change_id_;
251 }
252
253 void ViewManagerSynchronizer::RemoveFromPendingQueue(
254 ViewManagerTransaction* transaction) {
255 DCHECK_EQ(transaction, pending_transactions_.front());
256 pending_transactions_.erase(pending_transactions_.begin());
257 }
258
259 } // namespace view_manager
260 } // namespace services
261 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698