summaryrefslogtreecommitdiffstats
path: root/mojo/services/view_manager/root_node_manager.h
blob: e2e286c3a96b5651a02021a1145a3a349a309cbb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// 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.

#ifndef MOJO_SERVICES_VIEW_MANAGER_ROOT_NODE_MANAGER_H_
#define MOJO_SERVICES_VIEW_MANAGER_ROOT_NODE_MANAGER_H_

#include <map>

#include "base/basictypes.h"
#include "mojo/services/view_manager/ids.h"
#include "mojo/services/view_manager/node.h"
#include "mojo/services/view_manager/node_delegate.h"
#include "mojo/services/view_manager/root_view_manager.h"
#include "mojo/services/view_manager/view_manager_export.h"

namespace mojo {

class Shell;

namespace services {
namespace view_manager {

class View;
class ViewManagerConnection;

// RootNodeManager is responsible for managing the set of ViewManagerConnections
// as well as providing the root of the node hierarchy.
class MOJO_VIEW_MANAGER_EXPORT RootNodeManager : public NodeDelegate {
 public:
  // Used to indicate if the server id should be incremented after notifiying
  // clients of the change.
  enum ChangeType {
    CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID,
    CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID,
  };

  // Create when a ViewManagerConnection is about to make a change. Ensures
  // clients are notified of the correct change id.
  class ScopedChange {
   public:
    ScopedChange(ViewManagerConnection* connection,
                 RootNodeManager* root,
                 TransportChangeId change_id,
                 RootNodeManager::ChangeType change_type);
    ~ScopedChange();

   private:
    RootNodeManager* root_;
    const ChangeType change_type_;

    DISALLOW_COPY_AND_ASSIGN(ScopedChange);
  };

  explicit RootNodeManager(Shell* shell);
  virtual ~RootNodeManager();

  // Returns the id for the next ViewManagerConnection.
  TransportConnectionId GetAndAdvanceNextConnectionId();

  TransportChangeId next_server_change_id() const {
    return next_server_change_id_;
  }

  void AddConnection(ViewManagerConnection* connection);
  void RemoveConnection(ViewManagerConnection* connection);

  // Returns the connection by id.
  ViewManagerConnection* GetConnection(TransportConnectionId connection_id);

  // Returns the Node identified by |id|.
  Node* GetNode(const NodeId& id);

  // Returns the View identified by |id|.
  View* GetView(const ViewId& id);

  Node* root() { return &root_; }

  // These functions trivially delegate to all ViewManagerConnections, which in
  // term notify their clients.
  void NotifyNodeHierarchyChanged(const NodeId& node,
                                  const NodeId& new_parent,
                                  const NodeId& old_parent);
  void NotifyNodeViewReplaced(const NodeId& node,
                              const ViewId& new_view_id,
                              const ViewId& old_view_id);
  void NotifyNodeDeleted(const NodeId& node);
  void NotifyViewDeleted(const ViewId& view);

 private:
  // Used to setup any static state needed by RootNodeManager.
  struct Context {
    Context();
    ~Context();
  };

  // Tracks a change.
  struct Change {
    Change(TransportConnectionId connection_id,
           TransportChangeId client_change_id)
        : connection_id(connection_id),
          client_change_id(client_change_id) {
    }

    TransportConnectionId connection_id;
    TransportChangeId client_change_id;
  };

  typedef std::map<TransportConnectionId, ViewManagerConnection*> ConnectionMap;

  // Invoked when a particular connection is about to make a change. Records
  // the |change_id| so that it can be supplied to the clients by way of
  // OnNodeHierarchyChanged().
  // Changes should never nest, meaning each PrepareForChange() must be
  // balanced with a call to FinishChange() with no PrepareForChange()
  // in between.
  void PrepareForChange(ViewManagerConnection* connection,
                        TransportChangeId change_id);

  // Balances a call to PrepareForChange().
  void FinishChange(ChangeType change_type);

  TransportChangeId GetClientChangeId(
      TransportConnectionId connection_id) const;

  // Overriden from NodeDelegate:
  virtual void OnNodeHierarchyChanged(const NodeId& node,
                                      const NodeId& new_parent,
                                      const NodeId& old_parent) OVERRIDE;
  virtual void OnNodeViewReplaced(const NodeId& node,
                                  const ViewId& new_view_id,
                                  const ViewId& old_view_id) OVERRIDE;

  Context context_;

  // ID to use for next ViewManagerConnection.
  TransportConnectionId next_connection_id_;

  TransportChangeId next_server_change_id_;

  // Set of ViewManagerConnections.
  ConnectionMap connection_map_;

  // If non-null we're processing a change.
  scoped_ptr<Change> change_;

  RootViewManager root_view_manager_;

  // Root node.
  Node root_;

  DISALLOW_COPY_AND_ASSIGN(RootNodeManager);
};

}  // namespace view_manager
}  // namespace services
}  // namespace mojo

#endif  // MOJO_SERVICES_VIEW_MANAGER_ROOT_NODE_MANAGER_H_