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

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/cpp/shell/application.h"
11 #include "mojo/public/interfaces/shell/shell.mojom.h"
12 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
13
14 namespace mojo {
15 namespace services {
16 namespace view_manager {
17
18 class ViewManagerTransaction {
19 public:
20 virtual ~ViewManagerTransaction() {}
21
22 virtual bool Equals(ViewManagerTransaction* other) {
sky 2014/04/28 23:04:19 const ViewManagerTransaction* or const ViewManager
23 return other->type_ == type_;
24 }
25
26 virtual void Commit() = 0;
27
28 bool committed() const { return committed_; }
29 int change_id() const { return change_id_; }
sky 2014/04/28 23:04:19 uint32_t
30
31 protected:
32 enum TransactionType {
33 TYPE_CREATE_VIEW_TREE_NODE,
34 TYPE_HIERARCHY
sky 2014/04/28 23:04:19 Add description for TYPE_HIERARCH as it isn't obvi
35 };
36
37 ViewManagerTransaction(TransactionType type,
38 ViewManagerSynchronizer* synchronizer)
39 : type_(type),
40 change_id_(synchronizer->GetNextChangeId()),
41 committed_(false),
42 synchronizer_(synchronizer) {
43 }
44
45 IViewManager* service() { return synchronizer_->service_.get(); }
46
47 uint32_t MakeTransportId(uint16_t id) {
48 return (synchronizer_->connection_id_ << 16) | id;
49 }
50
51 int type_;
sky 2014/04/28 23:04:19 TransactionType?
sky 2014/04/28 23:04:19 Style guide says no protected members.
52 int change_id_;
sky 2014/04/28 23:04:19 Can this be const? And uint32_t.
53 bool committed_;
54 ViewManagerSynchronizer* synchronizer_;
55
56 private:
57 DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
58 };
59
60 class CreateViewTreeNodeTransaction
61 : public ViewManagerTransaction {
62 public:
63 CreateViewTreeNodeTransaction(int node_id,
64 ViewManagerSynchronizer* synchronizer)
65 : ViewManagerTransaction(TYPE_CREATE_VIEW_TREE_NODE, synchronizer),
66 node_id_(node_id) {}
67 virtual ~CreateViewTreeNodeTransaction() {}
68
69 private:
70 // Overridden from ViewManagerTransaction:
71 virtual bool Equals(ViewManagerTransaction* other) OVERRIDE {
72 return ViewManagerTransaction::Equals(other) &&
73 static_cast<CreateViewTreeNodeTransaction*>(other)->node_id_ ==
74 node_id_;
75 }
76 virtual void Commit() OVERRIDE {
77 DCHECK(!committed());
sky 2014/04/28 23:04:19 Maybe the DCHECK and boolean should be part of the
78 committed_ = true;
79 service()->CreateNode(
80 node_id_,
81 base::Bind(&CreateViewTreeNodeTransaction::OnActionCompleted,
82 base::Unretained(this)));
83 }
84
85 void OnActionCompleted(bool success) {
86 DCHECK(success);
87 // TODO(beng): Failure means we tried to create with an extant id for this
88 // connection. Figure out what to do.
89 }
90
91 int node_id_;
sky 2014/04/28 23:04:19 uint16_t I believe.
92
93 DISALLOW_COPY_AND_ASSIGN(CreateViewTreeNodeTransaction);
94 };
95
96 class HierarchyTransaction : public ViewManagerTransaction {
97 public:
98 enum HierarchyChangeType {
99 TYPE_ADD,
100 TYPE_REMOVE
101 };
102 HierarchyTransaction(HierarchyChangeType hierarchy_change_type,
103 int child_id,
104 int parent_id,
105 ViewManagerSynchronizer* synchronizer)
106 : ViewManagerTransaction(TYPE_HIERARCHY, synchronizer),
107 hierarchy_change_type_(hierarchy_change_type),
108 child_id_(child_id),
109 parent_id_(parent_id) {}
110 virtual ~HierarchyTransaction() {}
111
112 private:
113 // Overridden from ViewManagerTransaction:
114 virtual bool Equals(ViewManagerTransaction* other) OVERRIDE {
115 if (!ViewManagerTransaction::Equals(other))
116 return false;
117
118 HierarchyTransaction* hier_txn = static_cast<HierarchyTransaction*>(other);
119 return hier_txn->hierarchy_change_type_ == hierarchy_change_type_ &&
120 hier_txn->child_id_ == child_id_ &&
121 hier_txn->parent_id_ == parent_id_;
122 }
123 virtual void Commit() OVERRIDE {
124 DCHECK(!committed());
125 committed_ = true;
126 switch (hierarchy_change_type_) {
127 case TYPE_ADD:
sky 2014/04/28 23:04:19 nit: indentation is off for the switch statement.
128 service()->AddNode(MakeTransportId(parent_id_),
129 MakeTransportId(child_id_),
130 change_id_,
131 base::Bind(&HierarchyTransaction::OnActionCompleted,
132 base::Unretained(this)));
133 break;
134 case TYPE_REMOVE:
135 service()->RemoveNodeFromParent(
136 MakeTransportId(child_id_),
137 change_id_,
138 base::Bind(&HierarchyTransaction::OnActionCompleted,
139 base::Unretained(this)));
140 break;
141 default:
sky 2014/04/28 23:04:19 You should be able to remove this so that you get
142 NOTREACHED();
143 }
144 }
145
146 void OnActionCompleted(bool success) {
147 DCHECK(success);
148 // TODO(beng): Failure means either one of the nodes specified didn't exist,
149 // or we passed the same node id for both params. Roll back?
150 }
151
152 HierarchyChangeType hierarchy_change_type_;
sky 2014/04/28 23:04:19 const
153 int child_id_;
sky 2014/04/28 23:04:19 uint16_t for both of these.
154 int parent_id_;
155
156 DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction);
157 };
158
159 ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
160 : view_manager_(view_manager),
161 connected_(false),
162 connection_id_(0),
163 next_change_id_(0),
sky 2014/04/28 23:04:19 order doesn't match header.
164 next_id_(0) {
165 InterfacePipe<services::view_manager::IViewManager, AnyInterface>
166 view_manager_pipe;
167 AllocationScope scope;
168 ViewManagerPrivate(view_manager_).application()->shell()->Connect(
169 "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass());
170 service_.reset(view_manager_pipe.handle_to_self.Pass(), this);
171 }
172
173 ViewManagerSynchronizer::~ViewManagerSynchronizer() {
174 }
175
176 int ViewManagerSynchronizer::CreateViewTreeNode() {
177 int id = next_id_++;
178 pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this));
179 ScheduleSync();
180 return id;
181 }
182
183 void ViewManagerSynchronizer::AddChild(int child_id, int parent_id) {
184 pending_transactions_.push_back(
185 new HierarchyTransaction(HierarchyTransaction::TYPE_ADD,
186 child_id,
187 parent_id,
188 this));
189 ScheduleSync();
190 }
191
192 void ViewManagerSynchronizer::RemoveChild(int child_id, int parent_id) {
193 pending_transactions_.push_back(
194 new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE,
195 child_id,
196 parent_id,
197 this));
198 ScheduleSync();
199 }
200
201 ////////////////////////////////////////////////////////////////////////////////
202 // ViewManagerSynchronizer, IViewManagerClient implementation:
203
204 void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) {
205 connected_ = true;
206 connection_id_ = connection_id;
207 ScheduleSync();
208 }
209
210 void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32 node,
211 uint32 new_parent,
212 uint32 old_parent,
213 int32 change_id) {
214 // The service will still notify us about changes made from this connection,
215 // but we use our transaction queue as a record of what those changes were.
216 // We use this ack as an opportunity to remove these entries from our queue.
217 // Non-zero change_id is the service's way of telling us the change originated
218 // from this connection.
219 if (RemovedFromPendingQueue(change_id))
sky 2014/04/28 23:04:19 One problematic area is if a transaction generates
Ben Goodger (Google) 2014/04/29 00:00:54 Hrm and probably for nested hiers.
220 return;
221
222 if (change_id == 0) {
223 // TODO(beng): Apply changes from another client.
224 }
225
226 // TODO(beng): possible that changes from this client are never ack'ed? e.g.
227 // node creates are treated as txns & there is no ack.
228 }
229
230 void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node,
231 uint32_t new_view_id,
232 uint32_t old_view_id,
233 int32_t change_id) {
234 // ..
235 }
236
237 ////////////////////////////////////////////////////////////////////////////////
238 // ViewManagerSynchronizer, private:
239
240 void ViewManagerSynchronizer::ScheduleSync() {
241 base::MessageLoop::current()->PostTask(
242 FROM_HERE,
243 base::Bind(&ViewManagerSynchronizer::DoSync, base::Unretained(this)));
244 }
245
246 void ViewManagerSynchronizer::DoSync() {
247 // The service connection may not be set up yet. OnConnectionEstablished()
248 // will schedule another sync when it is.
249 if (!connected_)
250 return;
251
252 Transactions::const_iterator it = pending_transactions_.begin();
253 for (; it != pending_transactions_.end(); ++it) {
254 if (!(*it)->committed())
255 (*it)->Commit();
256 }
257 }
258
259 int ViewManagerSynchronizer::GetNextChangeId() {
260 // TODO(beng): update once change id becomes uint.
261 // TODO(beng): deal with change id collisions? Important in the "never ack'ed
262 // change" case mentioned in OnNodeHierarchyChanged().
263 // "0" is a special value passed to other connected clients, so we can't use
264 // it.
265 next_change_id_ = std::max(1, ++next_change_id_);
266 return next_change_id_;
267 }
268
269 bool ViewManagerSynchronizer::RemovedFromPendingQueue(int change_id) {
270 if (change_id != 0) {
271 Transactions::iterator it = pending_transactions_.begin();
sky 2014/04/28 23:04:19 I think you should only have to check the first tr
Ben Goodger (Google) 2014/04/29 00:00:54 Not quite. I currently have transactions for node
272 for (; it != pending_transactions_.end(); ++it) {
273 if ((*it)->change_id() == change_id) {
274 pending_transactions_.erase(it);
275 return true;
276 }
277 }
278 }
279 return false;
280 }
281
282 } // namespace view_manager
283 } // namespace services
284 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698